package com.mqtt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.mqtt.model.MqttMessage;
import com.mqtt.service.converter.ProtocolConverter;
import com.mqtt.utils.MessageParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 消息处理服务
 */
@Slf4j
@Service
public class MessageProcessService {
    
    @Autowired
    private ProtocolConverter protocolConverter;
    
    @Autowired
    private MessageParser messageParser;
    
    /**
     * 处理设备数据
     */
    public Map<String, Object> processDeviceData(MqttMessage mqttMessage) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 解析消息
            JSONObject data = messageParser.parse(mqttMessage.getPayload());
            
            // 数据验证
            if (!validateData(data)) {
                log.warn("Invalid data from device: {}", mqttMessage.getDeviceId());
                result.put("status", "error");
                result.put("message", "Invalid data format");
                return result;
            }
            
            // 数据转换
            Map<String, Object> convertedData = protocolConverter.convert(data.toJSONString());
            
            // 数据增强
            enrichData(convertedData, mqttMessage);
            
            // 数据处理
            processData(convertedData);
            
            result.put("status", "success");
            result.put("data", convertedData);
            result.put("deviceId", mqttMessage.getDeviceId());
            result.put("timestamp", mqttMessage.getTimestamp());
            
        } catch (Exception e) {
            log.error("Error processing device data", e);
            result.put("status", "error");
            result.put("message", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 处理告警数据
     */
    public Map<String, Object> processAlarmData(MqttMessage mqttMessage) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            JSONObject alarmData = JSON.parseObject(mqttMessage.getPayload());
            
            // 告警级别判断
            String level = determineAlarmLevel(alarmData);
            alarmData.put("level", level);
            
            // 告警分类
            String category = categorizeAlarm(alarmData);
            alarmData.put("category", category);
            
            // 添加设备信息
            alarmData.put("deviceId", mqttMessage.getDeviceId());
            alarmData.put("receivedTime", mqttMessage.getTimestamp());
            
            result.put("status", "success");
            result.put("alarm", alarmData);
            
            // 根据告警级别决定是否需要立即通知
            if ("critical".equals(level) || "high".equals(level)) {
                result.put("requiresNotification", true);
            }
            
        } catch (Exception e) {
            log.error("Error processing alarm data", e);
            result.put("status", "error");
            result.put("message", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 处理状态数据
     */
    public Map<String, Object> processStatusData(MqttMessage mqttMessage) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            JSONObject statusData = JSON.parseObject(mqttMessage.getPayload());
            
            // 状态解析
            String status = statusData.getString("status");
            
            // 状态转换
            Map<String, Object> statusInfo = new HashMap<>();
            statusInfo.put("deviceId", mqttMessage.getDeviceId());
            statusInfo.put("status", status);
            statusInfo.put("timestamp", mqttMessage.getTimestamp());
            
            // 添加额外的状态信息
            if (statusData.containsKey("details")) {
                statusInfo.put("details", statusData.getJSONObject("details"));
            }
            
            // 检查状态变化
            boolean statusChanged = checkStatusChange(mqttMessage.getDeviceId(), status);
            statusInfo.put("statusChanged", statusChanged);
            
            result.put("status", "success");
            result.put("statusInfo", statusInfo);
            
        } catch (Exception e) {
            log.error("Error processing status data", e);
            result.put("status", "error");
            result.put("message", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 数据验证
     */
    private boolean validateData(JSONObject data) {
        // 基本验证
        if (data == null || data.isEmpty()) {
            return false;
        }
        
        // 检查必要字段
        if (!data.containsKey("timestamp")) {
            return false;
        }
        
        // 时间戳验证
        try {
            long timestamp = data.getLongValue("timestamp");
            long currentTime = System.currentTimeMillis();
            
            // 检查时间戳是否在合理范围内（前后1小时）
            if (Math.abs(currentTime - timestamp) > 3600000) {
                log.warn("Timestamp out of range: {}", timestamp);
                return false;
            }
        } catch (Exception e) {
            log.error("Invalid timestamp format", e);
            return false;
        }
        
        return true;
    }
    
    /**
     * 数据增强
     */
    private void enrichData(Map<String, Object> data, MqttMessage mqttMessage) {
        // 添加接收时间
        data.put("receivedTime", mqttMessage.getTimestamp());
        
        // 添加数据来源
        data.put("source", "mqtt");
        data.put("topic", mqttMessage.getTopic());
        
        // 添加设备信息
        data.put("deviceId", mqttMessage.getDeviceId());
        data.put("deviceType", mqttMessage.getDeviceType());
        
        // 计算延迟
        if (data.containsKey("timestamp")) {
            long deviceTime = Long.parseLong(data.get("timestamp").toString());
            long delay = System.currentTimeMillis() - deviceTime;
            data.put("delay", delay);
        }
    }
    
    /**
     * 处理数据
     */
    private void processData(Map<String, Object> data) {
        // 数据处理逻辑
        // 可以进行数据清洗、转换、聚合等操作
        
        // 示例：单位转换
        if (data.containsKey("temperature")) {
            // 假设原始数据是摄氏度，转换为华氏度
            double celsius = Double.parseDouble(data.get("temperature").toString());
            double fahrenheit = celsius * 9.0 / 5.0 + 32;
            data.put("temperatureF", fahrenheit);
        }
        
        // 示例：数据范围检查
        if (data.containsKey("humidity")) {
            double humidity = Double.parseDouble(data.get("humidity").toString());
            if (humidity < 0 || humidity > 100) {
                log.warn("Humidity value out of range: {}", humidity);
                data.put("humidityValid", false);
            } else {
                data.put("humidityValid", true);
            }
        }
    }
    
    /**
     * 判断告警级别
     */
    private String determineAlarmLevel(JSONObject alarmData) {
        // 根据告警类型和值判断级别
        String type = alarmData.getString("type");
        
        if ("temperature".equals(type)) {
            double value = alarmData.getDoubleValue("value");
            if (value > 80) return "critical";
            if (value > 60) return "high";
            if (value > 40) return "medium";
            return "low";
        }
        
        // 默认级别
        return alarmData.getString("level") != null ? 
               alarmData.getString("level") : "medium";
    }
    
    /**
     * 告警分类
     */
    private String categorizeAlarm(JSONObject alarmData) {
        String type = alarmData.getString("type");
        
        if (type == null) {
            return "unknown";
        }
        
        // 根据类型分类
        if (type.contains("temperature") || type.contains("humidity")) {
            return "environmental";
        } else if (type.contains("power") || type.contains("voltage")) {
            return "electrical";
        } else if (type.contains("network") || type.contains("connection")) {
            return "communication";
        } else if (type.contains("security") || type.contains("intrusion")) {
            return "security";
        }
        
        return "other";
    }
    
    /**
     * 检查状态变化
     */
    private boolean checkStatusChange(String deviceId, String newStatus) {
        // 这里应该从缓存或数据库获取上一次的状态进行比较
        // 简化示例
        return true;
    }
}